home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / GX Libraries / ShapeLibrary.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-31  |  13.3 KB  |  448 lines  |  [TEXT/MPS ]

  1.  
  2. /*
  3.     File:        ShapeLibrary.c
  4.  
  5.     Contains:    graphics libraries - gxShape library
  6.     
  7.     Written by:    Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  8.     
  9.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.          <1>      1/9/95    JD        First checked in.
  14. */
  15.  
  16. #include <Memory.h>
  17. #include "GraphicsLibraries.h"
  18.  
  19. gxShape NewPolygon(const gxPolygon *polyData)
  20. {
  21.     gxShape sh;
  22.  
  23.     NilParamReturnNil(polyData);
  24.     sh = GXNewShape(gxPolygonType);
  25.     SetPolygon(sh, 0, polyData);
  26.     return sh;
  27. }
  28.  
  29. gxShape NewPath(const gxPath *pathData)
  30. {
  31.     gxShape sh;
  32.  
  33.     NilParamReturnNil(pathData);
  34.     sh = GXNewShape(gxPathType);
  35.     SetPath(sh, 0, pathData);
  36.     return sh;
  37. }
  38.  
  39. gxPath *GetPath(gxShape source, long contour, register gxPath *pathData)
  40. {
  41.     NilShapeReturnNil(source);
  42.     NilParamReturnNil(pathData);
  43.     {   register gxPaths *tempData;
  44.         long index = GXGetShapeIndex(source, contour, 1);
  45.         long points = GXCountShapePoints(source, contour);
  46.         long size = GXGetPathParts(source, index, points, nil);
  47.         
  48.         tempData = (gxPaths *) NewPtr(size);
  49.         NilParamReturnNil(tempData);
  50.         GXGetPathParts(source, index, points, tempData);
  51.         BlockMove(&tempData->contour[0], pathData, size - sizeof(long));
  52.         DisposePtr((Ptr) tempData);
  53.         return pathData;
  54.     }
  55. }
  56.  
  57. gxPolygon *GetPolygon(gxShape source, long contour, register gxPolygon *polygonData)
  58. {
  59.     NilShapeReturnNil(source);
  60.     NilParamReturnNil(polygonData);
  61.     {   register gxPolygons *tempData;
  62.         long index = GXGetShapeIndex(source, contour, 1);
  63.         long points = GXCountShapePoints(source, contour);
  64.         long size = GXGetPolygonParts(source, index, points, nil);
  65.     
  66.         tempData = (gxPolygons *) NewPtr(size);
  67.         NilParamReturnNil(tempData);
  68.         GXGetPolygonParts(source, index, points, tempData);
  69.         BlockMove(&tempData->contour[0], polygonData, size - sizeof(long));
  70.         DisposePtr((Ptr) tempData);
  71.         return polygonData;
  72.     }
  73. }
  74.  
  75. void SetPolygon(gxShape source, long contour, register const gxPolygon *polygonData)
  76. {
  77.     NilShapeReturn(source);
  78.     NilParamReturn(polygonData);
  79.     {   long size = (long) &((gxPolygons *) 0)->contour[0].vector[polygonData->vectors];
  80.         register gxPolygons *tempData;
  81.         
  82.         tempData = (gxPolygons *) NewPtr(size);
  83.         NilParamReturn(tempData);
  84.         BlockMove(polygonData, &tempData->contour[0], size - sizeof(long));
  85.         tempData->contours = 1;
  86.         if( contour )
  87.             GXSetPolygonParts(source, GXGetShapeIndex(source, contour, 1), GXCountShapePoints(source, contour), tempData, 0);
  88.         else
  89.             GXSetPolygons(source, tempData);
  90.         DisposePtr((Ptr) tempData);
  91.     }
  92. }
  93.  
  94. void SetPath(gxShape source, long contour, register const gxPath *pathData)
  95. {
  96.     NilShapeReturn(source);
  97.     NilParamReturn(pathData);
  98.     {   long size = ((long) &((gxPaths *) 0)->contour[0].vector[pathData->vectors]) + pathData->vectors / 32 * sizeof(long);
  99.         register gxPaths *tempData;
  100.     
  101.         tempData = (gxPaths *) NewPtr(size);
  102.         NilParamReturn(tempData);
  103.         BlockMove(pathData, &tempData->contour[0], size - sizeof(long));
  104.         tempData->contours = 1;
  105.         if( contour )
  106.             GXSetPathParts(source, GXGetShapeIndex(source, contour, 1), GXCountShapePoints(source, contour), tempData, 0);
  107.         else
  108.             GXSetPaths(source, tempData);
  109.         DisposePtr((Ptr) tempData);
  110.     }
  111. }
  112.  
  113. void DrawPolygon(const gxPolygon *polyData, gxShapeFill fill)
  114. {
  115.     gxShape sh;
  116.  
  117.     NilParamReturn(polyData);
  118.     sh = NewPolygon(polyData);
  119.     GXSetShapeFill(sh, fill);
  120.     GXDrawShape(sh);
  121.     GXDisposeShape(sh);
  122. }
  123.  
  124.  
  125. void DrawPath(const gxPath *pathData, gxShapeFill fill)
  126. {
  127.     gxShape sh;
  128.  
  129.     NilParamReturn(pathData);
  130.     sh = NewPath(pathData);
  131.     GXSetShapeFill(sh, fill);
  132.     GXDrawShape(sh);
  133.     GXDisposeShape(sh);
  134. }
  135.  
  136. void SetShapeIndexPoint(gxShape source, long index, const gxPoint *data)
  137. {
  138.     GXSetShapePoints(source, index, 1, data);
  139. }
  140.  
  141. gxPoint *GetShapeIndexPoint(gxShape source, long index, gxPoint *data)
  142. {
  143.     GXGetShapePoints(source, index, 1, data);
  144.     return data;
  145. }
  146.  
  147. void SetShapeIndexControl(gxShape source, long index, long control)
  148. {
  149.     NilShapeReturn(source);
  150.     if( GXGetShapeType(source) == gxPathType ) 
  151.     {   long pathData[6];
  152.     
  153.         GXGetPathParts(source, index, 1, (gxPaths *)pathData);
  154.         if( control )
  155.             pathData[2] = 0x80000000;
  156.         else
  157.             pathData[2] = 0x00000000;
  158.         GXSetPathParts(source, index, 1, (gxPaths *)pathData, 0);
  159.     } else
  160.         GXPostGraphicsWarning(graphic_type_does_not_contain_control_bits);
  161. }
  162.  
  163. long GetShapeIndexControl(gxShape source, long index, long *control)
  164. {
  165.     NilShapeReturnNil(source);
  166.     IfErrorReturnNil(index < 1 || index > GXCountShapePoints(source, 0), index_out_of_range);
  167.     {   gxShapeType theType = GXGetShapeType(source);
  168.         long result = 0;
  169.     
  170.         switch( theType )
  171.         {
  172.             case gxPathType:
  173.             {
  174.                 long pathData[6];
  175.                 GXGetPathParts(source, index, 1, (gxPaths *)pathData);
  176.                 if( pathData[2] )
  177.                     result = true;
  178.                 break;
  179.             }
  180.             case gxGlyphType:
  181.             {
  182.                 long bits;
  183.                 GXGetGlyphPositions(source, index, 1, &bits, nil);
  184.                 if( bits )
  185.                     result = true;
  186.                 break;
  187.             }
  188.             case gxCurveType:
  189.                 if( index == 2 )
  190.                     result = 1;
  191.         }
  192.     
  193.         if( control )
  194.             *control = result;
  195.         return result;
  196.     }
  197. }
  198.  
  199. void InsertShape(gxShape source, long index, gxShape toAdd)
  200. {
  201.     GXSetShapeParts(source, index, 0, toAdd, gxBreakLeftEdit + gxBreakRightEdit + gxRemoveDuplicatePointsEdit);
  202. }
  203.  
  204. gxShape ExtractShape(gxShape source, long firstPoint, long numPoints)
  205. {
  206.     gxShape newShape;
  207.  
  208.     newShape = GXGetShapeParts(source, firstPoint, numPoints, nil);
  209.     if( newShape )
  210.         GXSetShapeParts(source, firstPoint, numPoints, nil, gxRemoveDuplicatePointsEdit);
  211.     return newShape;
  212. }
  213.  
  214. void AddToShape(gxShape dest, gxShape add)
  215. {
  216.     GXSetShapeParts(dest, 0, 0, add, gxBreakLeftEdit);
  217. }
  218.  
  219. void ExtendShape(gxShape dest, gxShape add)
  220. {
  221.     GXSetShapeParts(dest, 0, 0, add, 0);
  222. }
  223.  
  224. #ifdef debugging
  225. gxShape NewShape2(gxShapeType typeID, long arg1, long arg2)
  226. {
  227.     IfWarningReturnNil(typeID != gxPointType, point_expected);
  228.     return NewShapeMany(typeID, arg1, arg2);
  229. }
  230.  
  231. gxShape NewShape4(gxShapeType typeID, long arg1, long arg2, long arg3, long arg4)
  232. {
  233.     IfWarningReturnNil(typeID != gxLineType && typeID != gxRectangleType, line_or_rectangle_expected);
  234.     return NewShapeMany(typeID, arg1, arg2, arg3, arg4);
  235. }
  236.  
  237. gxShape NewShape6(gxShapeType typeID, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6)
  238. {
  239.     IfWarningReturnNil(typeID != gxCurveType, curve_expected);
  240.     return NewShapeMany(typeID, arg1, arg2, arg3, arg4, arg5, arg6);
  241. }
  242.  
  243. void SetShape2(register gxShape dest, long arg1, long arg2)
  244. {
  245.     IfWarningReturn(GXGetShapeType(dest) != gxPointType, point_expected);
  246.     SetShapeMany(dest, arg1, arg2);
  247. }
  248.  
  249. void SetShape4(register gxShape dest, long arg1, long arg2, long arg3, long arg4)
  250. {
  251.     register gxShapeType typeID;
  252.  
  253.     NilShapeReturn(dest);
  254.     typeID = GXGetShapeType(dest);
  255.     IfWarningReturn(typeID != gxLineType && typeID != gxRectangleType, line_or_rectangle_expected);
  256.     SetShapeMany(dest, arg1, arg2, arg3, arg4);
  257. }
  258.  
  259. void SetShape6(register gxShape dest, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6)
  260. {
  261.     register gxShapeType typeID;
  262.  
  263.     NilShapeReturn(dest);
  264.     typeID = GXGetShapeType(dest);
  265.     IfWarningReturn(typeID != gxCurveType, curve_expected);
  266.     SetShapeMany(dest, arg1, arg2, arg3, arg4, arg5, arg6);
  267. }
  268. #endif
  269.  
  270. gxShape NewShapeMany(gxShapeType type, Fixed arg1, ...)
  271. {
  272.     return GXNewShapeVector(type, &arg1);
  273. }
  274.  
  275. void SetShapeMany(gxShape sourceShape, Fixed arg1, ...)
  276. {
  277.     NilShapeReturn(sourceShape);
  278.     GXSetShapeVector(sourceShape, &arg1);
  279. }
  280.  
  281. void CenterShape(gxShape target, gxRectangle *container)
  282. {
  283.     gxRectangle shapeBounds;
  284.     
  285.     NilShapeReturn(target);
  286.     NilParamReturn(container);
  287.     GXGetShapeBounds(target, 0, &shapeBounds);
  288.     GXMoveShape(target,   ((container->left + container->right) - (shapeBounds.left + shapeBounds.right))/2,
  289.                     ((container->top + container->bottom) - (shapeBounds.top + shapeBounds.bottom))/2);
  290. }
  291.  
  292. void MoveShapeCenterTo(gxShape target, Fixed x, Fixed y)
  293. {
  294.     gxPoint centerPt;
  295.    gxShapeAttribute oldAttributes = 0;
  296.    
  297.     NilShapeReturn(target);
  298.     GXGetShapeCenter(target, 0, ¢erPt);
  299.     if (GXGetShapeType(target) == gxLayoutType && (oldAttributes = GXGetShapeAttributes(target)) & gxMapTransformShape)
  300.         GXSetShapeAttributes(target, oldAttributes & ~gxMapTransformShape);
  301.     GXMoveShape(target, x - centerPt.x, y - centerPt.y);
  302.     if (oldAttributes & gxMapTransformShape)
  303.         GXSetShapeAttributes(target, oldAttributes);
  304. }
  305.  
  306. void RotateShapeAboutCenter(gxShape target, Fixed degrees)
  307. {
  308.     gxPoint centerPt;
  309.  
  310.     NilShapeReturn(target);
  311.     GXGetShapeCenter(target, 0, ¢erPt);
  312.     GXRotateShape(target, degrees, centerPt.x, centerPt.y);
  313. }
  314.  
  315. void SkewShapeAboutCenter(gxShape target, Fixed xSkew, Fixed ySkew)
  316. {
  317.     gxPoint centerPt;
  318.  
  319.     NilShapeReturn(target);
  320.     GXGetShapeCenter(target, 0, ¢erPt);
  321.     GXSkewShape(target, xSkew, ySkew, centerPt.x, centerPt.y);
  322. }
  323.  
  324. void ScaleShapeAboutCenter(gxShape target, Fixed hScale, Fixed vScale)
  325. {
  326.     gxPoint centerPt;
  327.  
  328.     NilShapeReturn(target);
  329.     GXGetShapeCenter(target, 0, ¢erPt);
  330.     GXScaleShape(target, hScale, vScale, centerPt.x, centerPt.y);
  331. }
  332.  
  333. void SetShapeOpenPath(gxShape target)
  334. {
  335.     long contours, i, index;
  336.  
  337.     NilShapeReturn(target);
  338. #ifdef debugging
  339.     GXIgnoreGraphicsNotice(type_already_set);
  340. #endif
  341.     GXSetShapeType(target, gxPathType);
  342. #ifdef debugging
  343.     GXPopGraphicsNotice();
  344.     GXIgnoreGraphicsNotice(parameters_have_no_effect);
  345. #endif
  346.     GXSetShapeFill(target, gxOpenFrameFill);
  347. #ifdef debugging
  348.     GXPopGraphicsNotice();
  349. #endif
  350.  
  351.     contours = GXCountShapeContours(target);
  352.     index = 0;
  353.     for (i = 1; i <= contours; i++) {
  354.         long points = GXCountShapePoints(target,i);
  355.         if (points) {
  356.             SetShapeIndexControl(target,index += 1,false);
  357.             SetShapeIndexControl(target,index += points-1,false);
  358.         }
  359.     }
  360. }
  361.  
  362. /*******************/
  363. /* drawing operations          */
  364. /*******************/
  365. static void CommonPaint(gxShape s, commonColor c)
  366. {
  367.     NilShapeReturn(s);
  368. #ifdef debugging    
  369.     GXIgnoreGraphicsNotice(color_already_set);
  370. #endif
  371.     SetShapeCommonColor(s,c);
  372. #ifdef debugging    
  373.     GXPopGraphicsNotice();
  374. #endif
  375.     GXDrawShape(s);
  376.     GXDisposeShape(s);
  377. }
  378.  
  379.  
  380. void PaintRectangle(const gxRectangle *r, commonColor c)
  381. {
  382.     CommonPaint(GXNewRectangle(r),c);
  383. }
  384.  
  385. void PaintRectangle2(const gxPoint *pt1, const gxPoint *pt2, commonColor c)
  386. {
  387.     CommonPaint(NewShape4(gxRectangleType, pt1->x, pt1->y, pt2->x, pt2->y),c);
  388. }
  389.  
  390. void PaintRectangle4(Fixed left, Fixed top, Fixed right, Fixed bottom, commonColor c)
  391. {
  392.     CommonPaint(NewShape4(gxRectangleType, left, top, right, bottom),c);
  393. }
  394.  
  395. /*******************/
  396. /* operations on geometries */
  397. /*******************/
  398.  
  399. void GetPathsIndexPointControl(const gxPaths *pathData, long index, gxPoint **pt, long **controlPtr, long *controlMask)
  400. {
  401.     NilParamReturn(pathData);
  402.     {   register long *pathWalker = (long *) pathData;
  403.         register short contours = *pathWalker++;
  404.         register short vectors;
  405.     
  406.         while (contours && index > (vectors = *pathWalker++)) {
  407.             pathWalker += (vectors + 31 >> 5) + (vectors << 1);
  408.             contours--;
  409.             index -= vectors;
  410.             }
  411.         if (contours) {
  412.             index--;
  413.             if (controlPtr)
  414.                 *controlPtr = &pathWalker[index >> 5];
  415.              if (controlMask)
  416.                 *controlMask = 0x80000000 >> (index & 31);
  417.             pathWalker += vectors + 31 >> 5;
  418.             if (pt)
  419.                 *pt = (gxPoint *) (pathWalker + (index << 1));
  420.         } else
  421.             GXPostGraphicsWarning(index_out_of_range_in_contour);
  422.     }
  423. }
  424.  
  425. /**************************/
  426. /* Get/GXSetBitmapParts utility routines */
  427. /**************************/
  428.  
  429. gxShape GetBitmapPartsFromFixedBounds(gxShape source, const gxRectangle *bounds)
  430. {
  431.     gxLongRectangle pixelBounds;
  432.     pixelBounds.top = FixedRound(bounds->top);          /* use = ((bounds->top + 0x00007fff) >> 16) if you want to include */
  433.     pixelBounds.left = FixedRound(bounds->left);            /* pixels whose centers touch the bounding gxRectangle on the top */
  434.     pixelBounds.bottom = FixedRound(bounds->bottom);        /* (the same applies for left, as well) */
  435.     pixelBounds.right = FixedRound(bounds->right);
  436.     return (GXGetBitmapParts(source, &pixelBounds));
  437. }
  438.  
  439. void SetBitmapPartsFromFixedBounds(gxShape target, const gxRectangle *bounds, gxShape bitmapShape)
  440. {
  441.     gxLongRectangle pixelBounds;
  442.     pixelBounds.top = FixedRound(bounds->top);          /* use = ((bounds->top + 0x00007fff) >> 16) if you want to include */
  443.     pixelBounds.left = FixedRound(bounds->left);            /* pixels whose centers touch the bounding gxRectangle on the top */
  444.     pixelBounds.bottom = FixedRound(bounds->bottom);
  445.     pixelBounds.right = FixedRound(bounds->right);
  446.     GXSetBitmapParts(target, &pixelBounds, bitmapShape);
  447. }
  448.